import axios, { AxiosError, AxiosResponse, InternalAxiosRequestConfig, AxiosRequestConfig } from "axios";
import { getMessageInfo } from "./status";
import { useUserStore } from "@/store";

interface BaseResponse<T = any> {
	code: number | string;
	message: string;
	data?: T;
}

const service = axios.create({
	baseURL: import.meta.env.VITE_APP_API_BASEURL,
	timeout: 5000,
});

// 请求拦截器
service.interceptors.request.use(
	(config: InternalAxiosRequestConfig) => {
		const userStore = useUserStore();
		if (userStore.asscessToken) {
			config.headers["Authorization"] = `Bearer ${userStore.asscessToken}`;
		}
		return config;
	},
	(error: AxiosError) => {
		console.log("request error", error);
		Promise.reject(error);
	},
);

// 响应拦截器
service.interceptors.response.use(
	(response: any) => {
		if (response.status === 200 || response.status === 201) {
			return response;
		}
	},
	(error: any) => {
		const { response } = error;
		if (response) {
			ElMessage({
				message: response.data.message || getMessageInfo(response.status),
				type: "error",
			});
			return Promise.reject(response);
		} else {
			ElMessage({
				message: "服务器连接失败",
				type: "error",
			});
			return Promise.reject(error);
		}
	},
);

/**
 * 创建一个通用的请求实例
 *
 * @template T 泛型类型，默认为 any
 * @param config 请求配置对象
 * @returns 返回一个 Promise，解析为 T 类型的响应数据
 */
const requestInstance = async <T = any>(config: AxiosRequestConfig): Promise<T> => {
	try {
		const res = await service.request<any, AxiosResponse<BaseResponse>>(config);
		const data = res.data;

		if (data.code !== 200 && data.code !== 201) {
			ElMessage.error(data.message || "请求失败");
			throw new Error(data.message || "请求失败");
		}

		return data as T;
	} catch (error) {
		// 可以统一处理一些通用错误
		console.error("Request error:", error);
		throw error; // 外层可继续catch
	}
};

// 在最后使用封装过的axios导出不同的请求方式
export function get<T = any, U = any>(config: AxiosRequestConfig, url: string, parms?: U): Promise<T> {
	return requestInstance({ ...config, url, method: "GET", params: parms });
}

export function post<T = any, U = any>(config: AxiosRequestConfig, url: string, data: U): Promise<T> {
	return requestInstance({ ...config, url, method: "POST", data: data });
}
export function patch<T = any, U = any>(config: AxiosRequestConfig, url: string, data: U): Promise<T> {
	return requestInstance({
		...config,
		url,
		method: "patch",
		data: data,
	});
}
export function deleteR<T = any, U = any>(config: AxiosRequestConfig, url: string, data?: U): Promise<T> {
	return requestInstance({
		...config,
		url: url,
		method: "delete",
		data: data,
	});
}

export default service;
